#include <iostream>

struct Base {
    void f(int x)
    {
        std::cout << "Base::f(int) " << x << "\n";
    }
};
struct Derived : Base {
    using Base::f;
    void f(double y, int x)
    {
        std::cout << "Derived::f(double) " << y << "\n";
    }
};

template <typename T>
T add(T a, T b)
{
    if (std::is_integral<T>::value) {
        std::cout << "Using integer addition.\n";
    } else if (std::is_floating_point<T>::value) {
        std::cout << "Using floating-point addition.\n";
    }
    return a + b;
}

template <typename A>
struct B {
    using type = typename A::type;
};

template <class T>
typename T::type h(typename B<T>::type);

template <class T>
auto h(typename B<T>::type) -> typename T::type; // redeclaration

template <class T>
void h(...) { }
template <class... Args>
void h(Args...) { }

using R = decltype(h<int>(0)); // ill-formed, no diagnostic required

int main()
{
    Derived d;
    d.f(42); // 错误！Base::f 被隐藏

    add(3, 4); // 输出：Using integer addition.
    add(3.5, 4.5); // 输出：Using floating-point addition.
}
